﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace QPEngine
{
    /// <summary>
    /// 单张扑克牌的结构
    /// </summary>
    public struct PokerInfo
    {
        public uint id;
        public string name;
        public uint color;
        public uint value;
        public string imge;
    }

    public static class PokerExten
    {
        /// <summary>
        /// 升序
        /// </summary>
        public static List<PokerInfo> QPAscending(this List<PokerInfo> self)
        {
            List<PokerInfo> poker = (from p in self orderby p.value ascending select p).ToList();
            return poker;
        }

        /// <summary>
        /// 降序
        /// </summary>
        public static List<PokerInfo> QPDescending(this List<PokerInfo> self)
        {
            List<PokerInfo> poker = (from p in self orderby p.value descending select p).ToList();
            return poker;
        }

        /// <summary>
        /// 最大值
        /// </summary>
        public static uint QPMaxValue(this List<PokerInfo> self)
        {
            return (from p in self select p.value).Max();
        }


        /// <summary>
        /// 扩展this List<PokerInfo>的tostring
        /// </summary>
        public static string QPToString(this List<PokerInfo> self)
        {
            string tmp = string.Empty;
            foreach (var item in self)
            {
                tmp += item.name;
            }
            return tmp;
        }

        /// <summary>
        /// 扩展this List<PokerInfo>的分组
        /// </summary>
        public static Dictionary<int, List<PokerInfo>> QPGroup(this List<PokerInfo> self)
        {
            Dictionary<int, List<PokerInfo>> dic = new Dictionary<int, List<PokerInfo>>();

            var values = from g in self group g by g.value into g2 orderby g2.Count() ascending select g2;

            foreach (var t1 in values)
            {
                List<PokerInfo> tmp = new List<PokerInfo>();
                foreach (var t2 in t1)
                {
                    tmp.Add(t2);
                }
                dic.Add(dic.Count + 1, tmp);
            }
            return dic;
        }

        /// <summary>
        /// 返回相同的元素
        /// </summary>
        public static List<PokerInfo> QPNoDistinct(this List<PokerInfo> self)
        {
            List<PokerInfo> pokers = new List<PokerInfo>();
            var dic = self.QPGroup();

            foreach (var k in dic)
            {
                foreach (var p in k.Value)
                {
                    pokers.Add(p);
                }
            }
            self = pokers;
            return pokers;
        }

    }

    /// <summary>
    /// 扑克牌
    /// </summary>
    public static class Poker
    {
        private static Dictionary<uint, PokerInfo> PokerDicInfo = new Dictionary<uint, PokerInfo>();
        /// <summary>
        /// 初始化54张扑克的信息
        /// </summary>
        static Poker()
        {
            PokerDicInfo[0] = new PokerInfo() { id = 103, name = "黑桃3", color = 1, value = 3, imge = "heitao3" };
            PokerDicInfo[1] = new PokerInfo() { id = 104, name = "黑桃4", color = 1, value = 4, imge = "heitao4" };
            PokerDicInfo[2] = new PokerInfo() { id = 105, name = "黑桃5", color = 1, value = 5, imge = "heitao5" };
            PokerDicInfo[3] = new PokerInfo() { id = 106, name = "黑桃6", color = 1, value = 6, imge = "heitao6" };
            PokerDicInfo[4] = new PokerInfo() { id = 107, name = "黑桃7", color = 1, value = 7, imge = "heitao7" };
            PokerDicInfo[5] = new PokerInfo() { id = 108, name = "黑桃8", color = 1, value = 8, imge = "heitao8" };
            PokerDicInfo[6] = new PokerInfo() { id = 109, name = "黑桃9", color = 1, value = 9, imge = "heitao9" };
            PokerDicInfo[7] = new PokerInfo() { id = 110, name = "黑桃10", color = 1, value = 10, imge = "heitao10" };
            PokerDicInfo[8] = new PokerInfo() { id = 111, name = "黑桃J", color = 1, value = 11, imge = "heitaoJ" };
            PokerDicInfo[9] = new PokerInfo() { id = 112, name = "黑桃Q", color = 1, value = 12, imge = "heitaoQ" };
            PokerDicInfo[10] = new PokerInfo() { id = 113, name = "黑桃K", color = 1, value = 13, imge = "heitaoK" };
            PokerDicInfo[11] = new PokerInfo() { id = 114, name = "黑桃A", color = 1, value = 14, imge = "heitaoA" };
            PokerDicInfo[12] = new PokerInfo() { id = 115, name = "黑桃2", color = 1, value = 15, imge = "heitao2" };

            PokerDicInfo[13] = new PokerInfo() { id = 203, name = "梅花3", color = 2, value = 3, imge = "meihua3" };
            PokerDicInfo[14] = new PokerInfo() { id = 204, name = "梅花4", color = 2, value = 4, imge = "meihua4" };
            PokerDicInfo[15] = new PokerInfo() { id = 205, name = "梅花5", color = 2, value = 5, imge = "meihua5" };
            PokerDicInfo[16] = new PokerInfo() { id = 206, name = "梅花6", color = 2, value = 6, imge = "meihua6" };
            PokerDicInfo[17] = new PokerInfo() { id = 207, name = "梅花7", color = 2, value = 7, imge = "meihua7" };
            PokerDicInfo[18] = new PokerInfo() { id = 208, name = "梅花8", color = 2, value = 8, imge = "meihua8" };
            PokerDicInfo[19] = new PokerInfo() { id = 209, name = "梅花9", color = 2, value = 9, imge = "meihua9" };
            PokerDicInfo[20] = new PokerInfo() { id = 210, name = "梅花10", color = 2, value = 10, imge = "meihua10" };
            PokerDicInfo[21] = new PokerInfo() { id = 211, name = "梅花J", color = 2, value = 11, imge = "meihuaJ" };
            PokerDicInfo[22] = new PokerInfo() { id = 212, name = "梅花Q", color = 2, value = 12, imge = "meihuaQ" };
            PokerDicInfo[23] = new PokerInfo() { id = 213, name = "梅花K", color = 2, value = 13, imge = "meihuaK" };
            PokerDicInfo[24] = new PokerInfo() { id = 214, name = "梅花A", color = 2, value = 14, imge = "meihuaA" };
            PokerDicInfo[25] = new PokerInfo() { id = 215, name = "梅花2", color = 2, value = 15, imge = "meihua2" };

            PokerDicInfo[26] = new PokerInfo() { id = 303, name = "方块3", color = 3, value = 3, imge = "fangkuai3" };
            PokerDicInfo[27] = new PokerInfo() { id = 304, name = "方块4", color = 3, value = 4, imge = "fangkuai4" };
            PokerDicInfo[28] = new PokerInfo() { id = 305, name = "方块5", color = 3, value = 5, imge = "fangkuai5" };
            PokerDicInfo[29] = new PokerInfo() { id = 306, name = "方块6", color = 3, value = 6, imge = "fangkuai6" };
            PokerDicInfo[30] = new PokerInfo() { id = 307, name = "方块7", color = 3, value = 7, imge = "fangkuai7" };
            PokerDicInfo[31] = new PokerInfo() { id = 308, name = "方块8", color = 3, value = 8, imge = "fangkuai8" };
            PokerDicInfo[32] = new PokerInfo() { id = 309, name = "方块9", color = 3, value = 9, imge = "fangkuai9" };
            PokerDicInfo[33] = new PokerInfo() { id = 310, name = "方块10", color = 3, value = 10, imge = "fangkuai10" };
            PokerDicInfo[34] = new PokerInfo() { id = 311, name = "方块J", color = 3, value = 11, imge = "fangkuaiJ" };
            PokerDicInfo[35] = new PokerInfo() { id = 312, name = "方块Q", color = 3, value = 12, imge = "fangkuaiQ" };
            PokerDicInfo[36] = new PokerInfo() { id = 313, name = "方块K", color = 3, value = 13, imge = "fangkuaiK" };
            PokerDicInfo[37] = new PokerInfo() { id = 314, name = "方块A", color = 3, value = 14, imge = "fangkuaiA" };
            PokerDicInfo[38] = new PokerInfo() { id = 315, name = "方块2", color = 3, value = 15, imge = "fangkuai2" };

            PokerDicInfo[39] = new PokerInfo() { id = 403, name = "红桃3", color = 4, value = 3, imge = "hongtao3" };
            PokerDicInfo[40] = new PokerInfo() { id = 404, name = "红桃4", color = 4, value = 4, imge = "hongtao4" };
            PokerDicInfo[41] = new PokerInfo() { id = 405, name = "红桃5", color = 4, value = 5, imge = "hongtao5" };
            PokerDicInfo[42] = new PokerInfo() { id = 406, name = "红桃6", color = 4, value = 6, imge = "hongtao6" };
            PokerDicInfo[43] = new PokerInfo() { id = 407, name = "红桃7", color = 4, value = 7, imge = "hongtao7" };
            PokerDicInfo[44] = new PokerInfo() { id = 408, name = "红桃8", color = 4, value = 8, imge = "hongtao8" };
            PokerDicInfo[45] = new PokerInfo() { id = 409, name = "红桃9", color = 4, value = 9, imge = "hongtao9" };
            PokerDicInfo[46] = new PokerInfo() { id = 410, name = "红桃10", color = 4, value = 10, imge = "hongtao10" };
            PokerDicInfo[47] = new PokerInfo() { id = 411, name = "红桃J", color = 4, value = 11, imge = "hongtaoJ" };
            PokerDicInfo[48] = new PokerInfo() { id = 412, name = "红桃Q", color = 4, value = 12, imge = "hongtaoQ" };
            PokerDicInfo[49] = new PokerInfo() { id = 413, name = "红桃K", color = 4, value = 13, imge = "hongtaoK" };
            PokerDicInfo[50] = new PokerInfo() { id = 414, name = "红桃A", color = 4, value = 14, imge = "hongtaoA" };
            PokerDicInfo[51] = new PokerInfo() { id = 415, name = "红桃2", color = 4, value = 15, imge = "hongtao2" };

            PokerDicInfo[52] = new PokerInfo() { id = 503, name = "小王", color = 5, value = 16, imge = "xiaowang" };
            PokerDicInfo[53] = new PokerInfo() { id = 504, name = "大王", color = 6, value = 17, imge = "dawang" };
        }

        /// <summary>
        /// 返回54张扑克
        /// </summary>
        /// <returns></returns>
        public static List<PokerInfo> Get()
        {
            List<PokerInfo> list = new List<PokerInfo>();
            foreach (var item in PokerDicInfo.Values)
            {
                list.Add(item);
            }
            return list;
        }

        /// <summary>
        /// 返回54张乱序扑克
        /// </summary>
        /// <returns></returns>
        public static List<PokerInfo> Get(bool sort)
        {
            List<PokerInfo> list = new List<PokerInfo>();
            if (sort)
            {
                int[] index = Enumerable.Range(0, 54).OrderBy(x => Guid.NewGuid()).ToArray();
                for (int i = 0; i < PokerDicInfo.Count; i++)
                {
                    list.Add(PokerDicInfo[(uint)index[i]]);
                }
            }
            else
            {
                var newDIC = PokerDicInfo.OrderByDescending((x) => x.Value.value);
                foreach (var item in newDIC)
                {
                    list.Add(item.Value);
                }
            }

            return list;
        }

        /// <summary>
        /// 通过扑克的ID获取信息
        /// </summary>
        public static PokerInfo Get(uint pokerID)
        {
            foreach (var item in PokerDicInfo)
            {
                if (item.Value.id.Equals(pokerID))
                {
                    return item.Value;
                }
            }
            return default(PokerInfo);
        }
        /// <summary>
        /// 通过扑克的名字（图片名字）获取
        /// </summary>
        public static PokerInfo Get(string pokerName)
        {
            int id = -1;
            foreach (var item in PokerDicInfo)
            {
                if (item.Value.name.Equals(pokerName))
                {
                    id = (int)item.Key; break;
                }
            }

            if (id >= 0) { return PokerDicInfo[(uint)id]; }

            foreach (var item in PokerDicInfo)
            {
                if (item.Value.imge.Equals(pokerName))
                {
                    id = (int)item.Key; break;
                }
            }
            if (id >= 0) { return PokerDicInfo[(uint)id]; }
            return default(PokerInfo);
        }

        /// <summary>
        /// 返回54张扑克的所有id
        /// </summary>
        public static List<uint> GetAllIDs()
        {
            List<uint> list = new List<uint>();
            for (int i = 0; i < PokerDicInfo.Count; i++)
            {
                list.Add(PokerDicInfo[(uint)i].id);
            }
            return list;
        }

        /// <summary>
        /// 返回54张扑克的所有名字
        /// </summary>
        public static List<string> GetAllNames()
        {
            List<string> list = new List<string>();
            for (int i = 0; i < PokerDicInfo.Count; i++)
            {
                list.Add(PokerDicInfo[(uint)i].name);
            }
            return list;
        }


        /// <summary>
        /// 返回number张扑克
        /// </summary>
        public static List<PokerInfo> GetPoker(uint number)
        {
            List<PokerInfo> poker = new List<PokerInfo>();
            int[] index = Enumerable.Range(0, 54).OrderBy(x => Guid.NewGuid()).ToArray();
            for (int i = 0; i < number; i++)
            {
                poker.Add(PokerDicInfo[(uint)index[i]]);
            }
            return poker;
        }

    }
}
